﻿using System;
using System.Collections;
using ImageEffects;
using RootMotion.FinalIK;
using UnityEngine;
using Yoozoo.Gameplay.Liberty.AI;
using RootMotion.Dynamics;

namespace Yoozoo.Gameplay.Liberty.PlayerController
{
    public class PlayerViewAvatar : MonoBehaviour
    {
        public LayerMask groundCastMask;
        public float gravity = -9.8f;
        
        public Transform playerModel;
        public Animator animator;

        public LightElement lightElement;
        
        // public float radarRadius;
        // public SphereCollider radarCollider;
        // public PlayerRadar radar;

        public Rigidbody rigidbody;
        public CapsuleCollider controllerCollider;
        public CapsuleCollider onHitTrigger;
        public SphereCollider headTrigger;

        public InputRootMotion inputRootMotion;
        
        public FullBodyBipedIK fullBodyBipedIK;
        public InteractionSystem interactionSystem;

        public BoneItemController boneItemController;

        public LocomotionAgent locomotionAgent;
        public PlayerAnimatorEvent playerAnimatorEvent;
        private PuppetMaster puppetMaster;
        private LibertyCarBirthManager _carBirthManager => LibertyAIUtils.AIManager.CarBirthManager;
        
        public void InitAvatar(GameObject go, AIEntity playerEntity)
        {
            go.transform.parent = transform.parent;
            go.transform.localPosition = Vector3.zero;
            go.transform.localEulerAngles = Vector3.zero;
            GameObject model = go;
            Transform puppetmasterTrans = go.transform.Find("PuppetMaster");
            if (puppetmasterTrans != null)
            {
                puppetMaster = puppetmasterTrans.GetComponent<PuppetMaster>();
                puppetMaster.mode = PuppetMaster.Mode.Disabled;
                puppetMaster.enabled = true;
                puppetMaster.OnDeath = OnPlayerDeath;
                model = go.transform.GetChild(2).gameObject;    // 0:Behaviours 1:PuppetMaster 2:model
                // if (go.name.Contains("RPG"))
                // {
                //     model = go.transform.Find("player_model_mid_RPG_controller").gameObject;
                // }
                // else
                // {
                //     model = go.transform.Find("player_model_mid_guidebank_controller").gameObject;
                // }
            }
            playerModel = model.transform;
            lightElement = model.GetComponent<LightElement>();
            animator = playerModel.GetComponent<Animator>();
            // radarCollider = model.AddComponent<SphereCollider>();
            // radarCollider.radius = radarRadius;
            // radarCollider.isTrigger = true;
            // radar = model.AddComponent<PlayerRadar>();
            // // 屏蔽
            // radarCollider.enabled = true;
            // radar.enabled = true;
            
            rigidbody = model.GetComponent<Rigidbody>();
            controllerCollider = model.GetComponent<CapsuleCollider>();

            inputRootMotion = model.GetOrAddComponent<InputRootMotion>();
            inputRootMotion.SetPlayerEntity(playerEntity);
            inputRootMotion.groundCastMask = groundCastMask;
            //inputRootMotion.gravity = gravity;
            
            fullBodyBipedIK = model.GetComponent<FullBodyBipedIK>();
            interactionSystem = model.GetComponent<InteractionSystem>();

            boneItemController = model.GetComponent<BoneItemController>();

            locomotionAgent = model.GetComponent<LocomotionAgent>();
            locomotionAgent.SyncTransform = model.transform.parent.parent;
            playerAnimatorEvent = model.GetComponent<PlayerAnimatorEvent>();
            
            // 伤害触发器
            GameObject onHitGameObject = new GameObject(LibertyAIUtils.PLAYER_AI_ID.ToString());
            onHitGameObject.layer = LayerMask.NameToLayer("RaycastCollider");
            onHitGameObject.tag = "Player";//SideType.Player.ToString();
            onHitTrigger = onHitGameObject.AddComponent<CapsuleCollider>();
            onHitTrigger.isTrigger = true;
            onHitTrigger.transform.SetParent(model.transform.transform);
            onHitTrigger.transform.localPosition = Vector3.zero;
            onHitTrigger.transform.localRotation = Quaternion.identity;
            // 头部伤害触发器
            GameObject headGameObject = new GameObject(LibertyAIUtils.PLAYER_AI_ID.ToString());
            headGameObject.layer = LayerMask.NameToLayer("RaycastCollider");
            headGameObject.tag = "Player";//SideType.Player.ToString();
            headTrigger = headGameObject.AddComponent<SphereCollider>();
            headTrigger.isTrigger = true;
            headTrigger.transform.SetParent(model.transform.transform);
            headTrigger.transform.localPosition = Vector3.zero;
            headTrigger.transform.localRotation = Quaternion.identity;
            // 玩家触发器
            PlayerTrigger playerTrigger = onHitGameObject.AddComponent<PlayerTrigger>();
            playerTrigger.InitData(playerEntity);
        }

        private void OnEnable()
        {
            if (LibertyAIUtils.PlayerController)
            {
                var playerTrans = LibertyAIUtils.PlayerController.playerModel;
                var playerData = LibertyAIUtils.PlayerController.playerEntity.AIEntity.data;
            
                LibertyAIUtils.PlayerController.inputController.Active = true;
                LibertyAIUtils.PlayerController.inputController.playInput.CloseMoveInput = false;
                LibertyAIUtils.PlayerController.inputController.playInput.CloseCameraInput = false;
                LibertyAIUtils.PlayerController.OnRegainBalance();
            
                playerData.npcStatus = NpcStatus.None;
                puppetMaster.state = PuppetMaster.State.Alive;
                puppetMaster.mode = PuppetMaster.Mode.Disabled;
            }
        }

        private void FixedUpdate()
        {
            //GetLegalPosition();
            transform.position = playerModel.position;
            transform.rotation = playerModel.rotation;
        }

        //0合法
        //1 下坠
        private int positionIllegalState;
        private float positionIllegalTime;
        private Vector3 lastPosition = Vector3.zero;

        //检测是否位置非法
        //小于0且持续下落且速度大于5
        //非法超过3秒，自动矫正
        private void GetLegalPosition()
        {
            var position = playerModel.position;
            if (lastPosition == Vector3.zero)
            {
                lastPosition = position;
                playerModel.position = position;
                return;
            }
            var targetState = 0;
            var drop = lastPosition.y - position.y;
            var speed = drop / Time.deltaTime;
            if (speed > 5)
            {
                targetState = 1;
            }
            else
            {
                targetState = 0;
            }

            if (positionIllegalState != targetState)
            {
                if (targetState == 1)
                {
                    positionIllegalTime = Time.time;
                }
                positionIllegalState = targetState;
            }
            

            if (positionIllegalState != 0 && Time.time - positionIllegalTime > 3)
            {
                positionIllegalState = 0;
                playerModel.position = new Vector3(position.x, 0.1f, position.z);
                puppetMaster.mode = PuppetMaster.Mode.Disabled;
                Debug.LogError("主角位置非法，已重置");
            }

            lastPosition = position;
        }
        
        public float bargeMinSpeed = 2;
        public float deadSpeed = 5;

        public void TriggerCollisionEnter(Collider collider)
        {
            CarEntity carEntity = _carBirthManager.GetCarEntity(collider);
            if (carEntity != null)
            {
                var playerData = LibertyAIUtils.PlayerController.playerEntity.AIEntity.data;
                float carSpeed = carEntity.carController.getForwardVelocity();
                if (playerData.isAlive && 
                    carSpeed > bargeMinSpeed && 
                    LibertyAIUtils.PlayerController.inputController.Active)
                {
                    StopAllCoroutines();
                    StartCoroutine(VehicleBarge(carEntity));
                }
            }
        }

        [Range(0,4)]
        public float deadDelayTime = 2f;
        private IEnumerator VehicleBarge(CarEntity carEntity)
        {
            var playerTrans = LibertyAIUtils.PlayerController.playerModel;
            var playerData = LibertyAIUtils.PlayerController.playerEntity.AIEntity.data;
            
            playerData.npcStatus = NpcStatus.VehicleBarge;

            Vector3 carPos = carEntity.position;
            Vector3 carDir = carEntity.forward;
            Vector3 carRight = carEntity.right;

            float angle = Vector3.Angle(carDir, playerTrans.position - carPos);
            float v = Vector3.Cross(carDir, playerTrans.position - carPos).y;

            LibertyAIUtils.PlayerController.inputRootMotion.isOutPlayerControl = true;
            LibertyAIUtils.PlayerController.inputController.Active = false;
            LibertyAIUtils.PlayerController.inputController.playInput.CloseMoveInput = true;
            LibertyAIUtils.PlayerController.inputController.playInput.CloseCameraInput = true;
            // LibertyAIUtils.PlayerController.playerEntity.AIEntity.viewer.animationAgent.EnterBattleState(BattleState.None);
            LibertyAIUtils.PlayerController.playerEntity.AIEntity.viewer.animationAgent.EnterAimingState(AimingState.None);
            LibertyAIUtils.PlayerController.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(true);
            LibertyAIUtils.PlayerController.playerEntity.AIEntity.data.moveSpeed = 0;
            
            if (angle < 25)
            {
                Vector3 bargeDir = playerTrans.forward;
                if (v > 0)
                {
                    //右边
                    bargeDir = -(carDir + carRight).normalized;
                }
                else
                {
                    //左边
                    bargeDir = -(carDir - carRight).normalized;
                }

                float angle2 = Vector3.Angle(carDir, playerTrans.forward);
                if (angle2 > 90)
                {
                    animator.CrossFade("vehicle_dead",0.08f,0);
                }
                else
                {
                    animator.CrossFade("vehicle_dead2",0.08f,0);
                }
                 
                inputRootMotion.isVehicleBarge = true;
                inputRootMotion.bargeDir = bargeDir;
                
                yield return new WaitForSeconds(deadDelayTime);
                puppetMaster.state = PuppetMaster.State.Dead;
                inputRootMotion.isVehicleBarge = false;
                yield return new WaitForSeconds(3);
            }
            else if(angle < 135)
            {
                animator.CrossFade("vehicle_scratch",0.2f,0);
                inputRootMotion.isVehicleScratch = true;
                inputRootMotion.bargeDir = (playerTrans.position - carPos).normalized;
                
                yield return new WaitForSeconds(1.5f);
                inputRootMotion.isVehicleScratch = false;
                yield return new WaitForSeconds(0.1f);
            }

            LibertyAIUtils.PlayerController.inputController.Active = true;
            LibertyAIUtils.PlayerController.inputController.playInput.CloseMoveInput = false;
            LibertyAIUtils.PlayerController.inputController.playInput.CloseCameraInput = false;
            LibertyAIUtils.PlayerController.OnRegainBalance();
            
            //carSeeker.isBarged = false;
            yield return new WaitForSeconds(0.5f);
            playerData.npcStatus = NpcStatus.None;
            LibertyAIUtils.PlayerController.inputRootMotion.isOutPlayerControl = false;
            LibertyAIUtils.PlayerController.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(false);
        }
        
        
        
        private IEnumerator PlayerDead2()
        {
            yield return new WaitForSeconds(deadDelayTime + 2);
            //var playerData = LibertyAIUtils.PlayerController.playerEntity.AIEntity.data;
            //playerData.npcStatus = NpcStatus.None;
            LibertyAIUtils.PlayerController.inputRootMotion.isVehicleBarge = false;
        }
        
        
        private void OnPlayerDeath()
        {
            Debug.Log("OnPlayerDeath");
            puppetMaster.state = PuppetMaster.State.Alive;
        }
    }
}